package com.test.springboot.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.test.springboot.bean.Employee;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;

import java.time.Duration;

/**
 * 自定义redis配置
 *
 * @create: 2019-06-27 15:35
 **/
@Configuration
public class MyRedisConfig {

    /**
     * redis模版，RedisCacheManager在操作数据缓存时使用，我们可以在这里指定序列化的机制。
     * 可以作用于序列化和反序列化
     *
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public RedisTemplate<Object, Employee> empRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Employee> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        //自定义序列化规则原来json
        template.setDefaultSerializer(new Jackson2JsonRedisSerializer<>(Employee.class));
        return template;
    }


//    @Bean  springboot2.0以上无法再使用这个方法来创建RedisCacheManager了
//    public RedisCacheManager employeeCacheManager(RedisTemplate<Object, Employee> empRedisTemplate){
//        RedisCacheManager cacheManager = new RedisCacheManager(empRedisTemplate);
//
//    }

    /**
     * 缓存管理器
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        //初始化一个RedisCacheWriter
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);

        //设置CacheManager的值序列化方式为json序列化
        //设置所有对象在序列化时都使用json规则
        RedisSerializer<Object> jsonSerializer = new GenericJackson2JsonRedisSerializer();
        //RedisSerializer<Object> jsonSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        /*
        在这里为什么不使用Jackson2JsonRedisSerializer而是使用GenericJackson2JsonRedisSerializer：
        GenericJackson2JsonRedisSerializer在反序列化时会生成一个@class的属性，表示这个json是什么类型的类。
        而Jackson2JsonRedisSerializer则不会生成这个属性，所以在反序列化时如果没有@class属性在这里则无法识别，
        这是一个什么类型的json数据，从而也无法转换成对应的类对象
         */
        RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair
                .fromSerializer(jsonSerializer);

        //只有在employee对象时才使用json规则
//        RedisSerializer<Employee> jsonSerializer = new Jackson2JsonRedisSerializer<>(Employee.class);
//        RedisSerializationContext.SerializationPair<Employee> pair = RedisSerializationContext.SerializationPair
//                .fromSerializer(jsonSerializer);

        RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig()
                .serializeValuesWith(pair);
        //设置默认超过期时间是30秒
        defaultCacheConfig.entryTtl(Duration.ofSeconds(30));
        //初始化RedisCacheManager
        return new RedisCacheManager(redisCacheWriter, defaultCacheConfig);
    }

}
